package controllers

import (
	"../../../deps/lessgo/net/httpclient"
	"../../../deps/lessgo/pagelet"
	"../../../deps/lessgo/utils"
	"../../../deps/lessgo/utilx"
	"../../base"
	"../../state"
	"../../store"
	"../models/session"
	"fmt"
	"io"
	"strconv"
)

var (
	bucketAccessKeyStatus = map[int]string{
		0: "Disable",
		1: "Active",
	}
)

type Bucket struct {
	*pagelet.Controller
}

func (c Bucket) ListAction() {

	if !session.IsLogin(c.Request) {
		return
	}

	ls, _ := store.NodeGet("/sys/bs")
	bs := []map[string]interface{}{}
	for _, v := range ls.N {

		if v.T != store.NodeTypeKey {
			continue
		}

		rs, err := store.NodeGet(v.P)
		if err != nil {
			continue
		}

		var b base.Bucket
		err = rs.ReplyJson(&b)
		if err == nil && b.Name != "" {

			rsState, _ := store.Cmd("HMGET", store.NodeData+v.P[len("/sys/bs/"):],
				store.NodeSepNum, store.NodeSepSize).List()
			rsStateKeys, _ := strconv.ParseInt(rsState[0], 10, 64)
			rsStateSize, _ := strconv.ParseFloat(rsState[1], 10)

			rsStateSizeDisplay := ""
			if rsStateSize > 1073741824 {
				rsStateSizeDisplay = fmt.Sprintf("%.2f GB", rsStateSize/1073741824)
			} else if rsStateSize > 1048576 {
				rsStateSizeDisplay = fmt.Sprintf("%.2f MB", rsStateSize/1048576)
			} else if rsStateSize > 1024 {
				rsStateSizeDisplay = fmt.Sprintf("%.2f KB", rsStateSize/1024)
			} else {
				rsStateSizeDisplay = fmt.Sprintf("%.0f Bytes", rsStateSize)
			}

			rsKeys, _ := store.Cmd("SMEMBERS", "sys:b2ak:"+b.Name).List()

			bs = append(bs, map[string]interface{}{
				"name":                 b.Name,
				"desc":                 b.Desc,
				"dataSize":             b.DataSize,
				"stateDataKeys":        rsStateKeys,
				"stateDataSize":        rsStateSize,
				"stateDataSizeDisplay": rsStateSizeDisplay,
				"accessKeys":           len(rsKeys),
				"created":              utilx.TimeParse(b.Created, "atom"),
				"updated":              utilx.TimeParse(b.Updated, "atom"),
			})
		}
	}
	c.ViewData["list"] = bs
}

func (c Bucket) SetAction() {

	if !session.IsLogin(c.Request) {
		return
	}

	name := c.Params.Get("name")

	var bucket base.Bucket
	rs, err := store.NodeGet("/sys/bs/" + name)
	if err == nil {
		rs.ReplyJson(&bucket)
	}

	if bucket.Name == "" {

		c.ViewData["name"] = utils.StringNewRand36(6)
		c.ViewData["datasize"] = 100

		c.ViewData["panel_title"] = "Create a New Bucket"
		c.ViewData["action_new"] = true

	} else {

		c.ViewData["name"] = bucket.Name
		c.ViewData["desc"] = bucket.Desc
		c.ViewData["ownerName"] = bucket.OwnerName
		c.ViewData["ownerEmail"] = bucket.OwnerEmail
		c.ViewData["datasize"] = bucket.DataSize

		c.ViewData["panel_title"] = "Edit Bucket"
		c.ViewData["action_new"] = false
	}
}

func (c Bucket) AccessKeysAction() {

	if !session.IsLogin(c.Request) {
		return
	}

	// TODO
	hc := httpclient.Get("http://" + state.Leader.Addr +
		":1777/v1/bucket/access-keys?bucket_name=" + c.Params.Get("name"))
	hc.SetTimeout(3)

	var rsp struct {
		ResponseJson
		Data []base.BucketAccessKey `json:"data"`
	}
	err := hc.ReplyJson(&rsp)
	if err == nil {
		ls := []map[string]interface{}{}
		for _, ak := range rsp.Data {

			status_display := ""
			if vd, ok := bucketAccessKeyStatus[ak.Status]; ok {
				status_display = vd
			}

			ls = append(ls, map[string]interface{}{
				"id":             ak.Id,
				"secret":         ak.Secret,
				"status":         ak.Status,
				"status_display": status_display,
				"created":        utilx.TimeParse(ak.Created, "atom"),
			})
		}
		c.ViewData["list"] = ls
	}

	c.ViewData["bucket_name"] = c.Params.Get("name")
}

func (c Bucket) AccessKeySetAction() {

	c.AutoRender = false

	var rsp struct {
		ResponseJson
	}
	rsp.ApiVersion = apiVersion
	rsp.Status = 400
	rsp.Message = "Bad Request"

	defer func() {
		if rspj, err := utils.JsonEncode(rsp); err == nil {
			io.WriteString(c.Response.Out, rspj)
		}
	}()

	if !session.IsLogin(c.Request) {
		return
	}

	// TODO
	hc := httpclient.Get("http://" + state.Leader.Addr +
		":1777/v1/bucket/access-key-set?access_key_id=" +
		c.Params.Get("keyid") + "&status=" + c.Params.Get("status"))
	hc.SetTimeout(3)
	err := hc.ReplyJson(&rsp)
	if err != nil {
		return
	}

	rsp.Status = 200
	rsp.Message = ""
}

func (c Bucket) AccessKeyNewAction() {

	c.AutoRender = false

	var rsp struct {
		ResponseJson
		Data base.BucketAccessKey `json:"data"`
	}
	rsp.ApiVersion = apiVersion
	rsp.Status = 400
	rsp.Message = "Bad Request"

	defer func() {
		if rspj, err := utils.JsonEncode(rsp); err == nil {
			io.WriteString(c.Response.Out, rspj)
		}
	}()

	if !session.IsLogin(c.Request) {
		return
	}

	// TODO
	hc := httpclient.Get("http://" + state.Leader.Addr +
		":1777/v1/bucket/access-key-new?bucket_name=" + c.Params.Get("bucket_name"))
	hc.SetTimeout(3)

	var upRsp struct {
		ResponseJson
		Data base.BucketAccessKey `json:"data"`
	}
	err := hc.ReplyJson(&upRsp)
	if err != nil {
		return
	}

	rsp = upRsp
}
